﻿/** \file
* \$Rev: 188 $
* 
* \$Date: 2010-04-27 22:02:26 +0000 (Tue, 27 Apr 2010) $
*
* \$URL: http://chorus-twitter.googlecode.com/svn/trunk/src/gui/NameList.cs $
*/

using System;
using System.Drawing;
using System.Windows.Forms;

namespace chorus.gui
{
	/// <summary>
	/// A strongly typed generic list control that supports binding and
	/// in-place item creation and deletion.
	/// </summary>
	/// <typeparam name="DataType">The type of item that populates the list.</typeparam>
	public partial class NameList<DataType> : ListBox
		where DataType : IDisplayNamed, new()
	{
		/// <summary>Whether to postpone data renames and additions.</summary>
		/// <summary>The event fired when a new item is created.</summary>
		public event Action<DataType> NewItem;
		/// <summary>The binding object.</summary>
		protected BindingSource Bind { get { return (BindingSource)DataSource; } }

		/// <summary>The constructor.</summary>
		public NameList() { InitializeComponent(); }

		#region Event handlers

		/// <summary>Fired when the selection changes.</summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event parameters.</param>
		void NameList_SelectedIndexChanged(object sender, EventArgs e)
		{
			menuDelete.Enabled = SelectedIndex != -1;
		}

		/// <summary>Fired when the user creates a new item.</summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event parameters.</param>
		void menuNew_Click(object sender, EventArgs e)
		{
			DataType item = (DataType)Bind.AddNew();
			if (NewItem != null)
				NewItem(item);
		}

		/// <summary>Fired when the user deletes an item.</summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event parameters.</param>
		void menuDelete_Click(object sender, EventArgs e) { Bind.RemoveCurrent(); }

		/// <summary>Fired when the user opens the context menu.</summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event parameters.</param>
		void contextMenu_Opened(object sender, EventArgs e)
		{
			Point p = PointToClient(contextMenu.Bounds.Location);
			int index = IndexFromPoint(p);
			if (index == -1)
				Bind.MoveLast();
			else
				Bind.Position = index;
		}

		#endregion
	}

	/// <summary>A NameList containing source containers.</summary>
	public class SourceContainerList : NameList<net.SourceContainer> { }

	/// <summary>
	/// Classes that get bound to a NameList need to implement this.
	/// </summary>
	public interface IDisplayNamed
	{
		/// <summary>The display name.</summary>
		string DisplayName { get; }
	}
}
